<pre class='metadata'>
Title: CSS Transitions Module Level 2
Status: ED
Work Status: Exploring
Shortname: css-transitions
Level: 2
Group: csswg
TR: https://www.w3.org/TR/css-transitions-2/
ED: https://drafts.csswg.org/css-transitions-2/
Previous Version: https://www.w3.org/TR/2023/WD-css-transitions-2-20230905/
Editor: L. David Baron, Google https://www.google.com, https://dbaron.org/, w3cid 15393
Editor: Brian Birtles, Invited Expert, brian@birchill.co.jp, w3cid 43194
Issue Tracking: Bugzilla bugs for all levels https://www.w3.org/Bugs/Public/buglist.cgi?product=CSS&amp;component=Transitions&amp;resolution=---
Abstract: CSS Transitions allows property changes in CSS values to occur smoothly over a specified duration.
Ignored Terms: translate, rotate, scale
</pre>
<pre class=anchors>
urlPrefix: https://dom.spec.whatwg.org/; type: dfn; spec: dom
    text: event target
</pre>
<pre class=link-defaults>
spec:css-borders-4; type:property; text:border-left-width
spec:css-transitions-1; type:value; text:all
spec:css-transitions-1; type:dfn; text:cancel
spec:html; type:dfn; text:being rendered
spec:web-animations-1; type:dfn;
    text:active duration
    text:active time
    text:animation class
    text:animation effect
    text:animation playback events
    text:associated effect
    text:associated effect end
    text:cancel an animation
    text:current time; for:animation
    text:current iteration
    text:fill mode
    text:idle; for:play state
    text:iteration duration
    text:iteration start
    text:pending pause task
    text:pending play task
    text:start delay
    text:unresolved
</pre>

<style type="text/css">
  table.event-state-transitions {
    width: 100%;
    border-spacing: 0px;
    border-collapse: collapse;
  }
  table.event-state-transitions th:first-child {
    width: 30%;
  }
  table.event-state-transitions th {
    text-align: center;
  }
  table.event-state-transitions td {
    padding: 0.2em 1em;
    border: 1px solid black;
  }
</style>

<h2 id="delta">Delta specification</h2>

  <p>This is a delta specification, meaning that it currently contains
  only the differences from CSS Transitions Level 1 [[!CSS-TRANSITIONS-1]].
  Once the Level 1 specification is closer to complete, it will be merged
  with the additions here into a complete level 2 specification.</p>


# Transitions # {#transitions}

<h3 id="transition-property-property" oldids="transition-name-property">The 'transition-property' Property</h3>

ISSUE: Insert text from [[css-transitions-1#transition-property-property]]
and backport the following paragraph.

Although the 'transition-property' may specify shorthand properties and the
''all'' keyword, individual transitions are generated for each longhand
sub-property that is [=transitionable=]. The <dfn>expanded transition property
name</dfn> of a transition is the name of the longhand sub-property for which
the transition was generated (e.g. 'border-left-width').

ISSUE: Update the defining instance of [=transitionable=]
once it is ported from Level 1.

In CSS Transitions Level 2, when comparing the [=before-change style=] and
[=after-change style=] for a given property, the property values are
<dfn>transitionable</dfn> if:
<ol>
 <li>They have an [=animation type=] that is neither [=not animatable=] nor
 [=discrete=], or</li>
 <li>The 'transition-behavior' is ''allow-discrete'' and they have an
 [=animation type=] that is [=discrete=].</li>
</ol>

Note: When values with a [=discrete=] [=animation type=] are transitioned, they
flip at 50% progress.

## The 'transition-duration' Property ## {#transition-duration-property}

The 'transition-duration' property specifies the [=iteration duration=]
of the transition's associated [=animation effect=].

## The 'transition-timing-function' Property ## {#transition-timing-function-property}

The 'transition-timing-function' property specifies the [=timing function=]
of the transition's associated [=animation effect=]
(see [[web-animations-1#time-transformations]]).

Note: Unlike CSS animations, the timing function for CSS transitions applies to
the animation effect as opposed to the individual keyframes since this allows
it to be reflected in the <a>transformed progress</a> as used when calculating
the reversing shortening factor.

## The 'transition-delay' Property ## {#transition-delay-property}

The 'transition-delay' property specifies the [=start delay=]
of the transition's associated [=animation effect=].

## The 'transition-behavior' Property ## {#transition-behavior-property}

The 'transition-behavior' property specifies whether transitions will be
started or not for discrete properties.

<pre class="propdef">
  Name: transition-behavior
  Value: <<transition-behavior-value>>#
  Initial: normal
  Applies to: All elements
  Inherited: no
  Percentages: N/A
  Computed value: as specified
  Canonical order: per grammar
  Animation type: not animatable
</pre>

The syntax for specifying 'transition-behavior' is as follows:

<div class=prod><dfn><<transition-behavior-value>></dfn> = normal | allow-discrete</div>

When ''transition-behavior-value/normal'' is specified, transitions will not be
started for discrete properties, only for interpolable properties. When
''allow-discrete'' is specified, transitions will be started for discrete
properties as well as interpolable properties.

## The 'transition' Shorthand Property ## {#transition-shorthand-property}

The syntax for specifying an item in the 'transition' shorthand is as follows:

<div class="prod">
  <dfn type id="single-transition">&lt;single-transition&gt;</dfn> = [ ''transition-property/none'' | <<single-transition-property>> ] || <<time>> || <<easing-function>> || <<time>> || <<transition-behavior-value>>
</div>


# Starting of transitions # {#starting}

The <dfn>owning element</dfn> of a transition refers to the element or
pseudo-element to which the 'transition-property' property was applied that
generated the animation.
A transition may be disassociated from its [=owning element=]
such that it has no [=owning element=].

The set of [=running transitions=] includes
only those transitions that have an [=owning element=].

Whenever an implementation is required to [=cancel=] a transition,
it must disassociate the transition from its [=owning element=]
and run the procedure to [=cancel an animation=] on the transition.

Although not explicitly defined by level 1 of this specification,
in addition to [=cancel|canceling=] transitions on elements that
are no longer [=connected=],
implementations must also [=cancel=] any running transitions
on elements that are no longer [=being rendered=] and
remove transitions on them from the set of [=completed transitions=].

Note that calling the {{Animation/cancel()}} method
on the {{CSSTransition}} object representing a [=running transition=]
does <em>not</em> cause the transition to be disassociated
from its [=owning element=].

## Faster reversing of interrupted transitions ## {#reversing}

The [=reversing shortening factor=] and [=reversing-adjusted start value=]
associated with a transition in order to produce correct reverse behavior,
are associated with the transition itself and not, for example,
its [=animation effect=].
As a result, transitions will use these same values when producing a
reversed transition, even if the transition's associated [=animation effect=]
has been updated or replaced using the Web Animations API [[WEB-ANIMATIONS]].

## The current transition generation ## {#current-transition-generation-section}

Associated with each top-level browsing context is a <dfn>current transition
generation</dfn> that is incremented on each <a>style change event</a>.

Each time a new transition is generated, the current value of the (already
incremented) <a>current transition generation</a> is stored as the
transition's <dfn>transition generation</dfn>.

## Defining [=before-change style=]: the ''@starting-style'' rule ## {#defining-before-change-style}

In Level 1 of this specification, transitions can only start during a
[=style change event=] for elements which have a defined [=before-change style=]
established by the previous [=style change event=]. That means a transition
could not be started on an element that was not being rendered for the previous
[=style change event=] (see: [[css-transitions-1#starting]]).

In some cases it makes sense to start transitions on newly inserted elements or
elements that change from not [=being rendered=] to being rendered. To allow
for that, this specification introduces ''@starting-style''.

The <dfn at-rule id="at-ruledef-starting-style">@starting-style</dfn> rule is a
grouping rule.  The style rules inside it are used to establish styles to
transition from, if the previous [=style change event=] did not establish a
[=before-change style=] for the element whose styles are being computed.

Note: This means that ''@starting-style'' rules only apply to some elements
during a computed style update, namely elements that were not rendered or part
of the DOM during the previous [=style change event=].

Define <dfn>starting style</dfn> for an element as the [=after-change style=]
with ''@starting-style'' rules applied in addition. If an element does not have
a [=before-change style=] for a given [=style change event=], the
[=starting style=] is used instead of the [=before-change style=] to compare
with the [=after-change style=] to start transitions
([[css-transitions-1#starting]]).

The rules inside ''@starting-style'' cascade as any other grouped style rules
without introducing any new ordering to the cascade, which means rules inside
''@starting-style'' do not necessarily win over those outside.

Style rules in ''@starting-style'' do not apply to [=after-change style=].
Thus, the presence of matching rules in ''@starting-style'' can cause
transitions to occur on elements that otherwise could not have transitions
because they lack a [=before-change style=].

[=Starting style=] inherits from the parent's [=after-change style=] just like
[=after-change style=] does.

<div class=example>

  The 'background-color' of an <code>h1</code> element can be transitioned
  from transparent to green when it is initially rendered:

  <pre class=lang-css>
  h1 {
    transition: background-color 1.5s;
    background-color: green;
  }
  @starting-style {
    h1 {
      background-color: transparent;
    }
  }
  </pre>

  Conditional rules can be used with CSS Nesting:

  <pre class=lang-css>
  h1 {
    transition: background-color 1.5s;
    background-color: green;
    @starting-style {
      background-color: transparent;
    }
  }
  </pre>
</div>

<div class=example>
  The 'opacity' of an element can be transitioned when the element changes
  to or from ''display: none'':

  <pre class=lang-css>
  #target {
    transition-property: opacity, display;
    transition-duration: 0.5s;
    display: block;
    opacity: 1;
    @starting-style {
      opacity: 0;
    }
  }
  #target.hidden {
    display: none;
    opacity: 0;
  }
  </pre>

  The display is transitioning to allow for an opacity transition before
  flipping from ''display:block'' to ''display:none''.

  Specifying ''opacity: 0'' in the ''@starting-style'' rule means the
  element will transition opacity from ''0'' to ''1'' when inserted into
  the tree or when the <code>hidden</code> class flips 'display' from
  ''display/none'' to ''display/block'' as the target element does not
  already have a [=before-change style=] in those cases.

  Specifying ''opacity: 0'' in the <code>#target.hidden</code> rule makes
  'opacity' transition from ''1'' to ''0'' when the <code>hidden</code>
  class is added.
</div>

Global, name-defining at-rules such as ''@keyframes'', ''@font-face'', and
''@layer'' are allowed inside ''@starting-style'', and when present behave as
if they were outside of ''@starting-style''.

### The <code>CSSStartingStyleRule</code> interface ### {#the-cssstartingstylerule-interface}

The {{CSSStartingStyleRule}} interface represents a ''@starting-style'' rule.

<pre class='idl'>
[Exposed=Window]
interface CSSStartingStyleRule : CSSGroupingRule {
};
</pre>


# Application of transitions # {#application}

## Animation composite order ## {#animation-composite-order}

<a spec='web-animations-1'>Animations</a> generated from the markup defined in
this specification have an <a>animation class</a> of &lsquo;CSS
Transition&rsquo;.

CSS Transitions have an <em>earlier</em> composite order that CSS Animations
and animations without a specific <a>animation class</a>.

Within the set of CSS Transitions, two animations <var>A</var> and <var>B</var>
are sorted in composite order (first to last) as follows:

1.  If neither <var>A</var> nor <var>B</var> has an <a>owning element</a>,
    sort based on their relative position in the <a>global animation list</a>.

1.  Otherwise, if  only one of <var>A</var> or <var>B</var> has an <a>owning
    element</a>, let the animation <em>with</em> an <a>owning element</a> sort
    first.

1.  Otherwise, if the <a>owning element</a> of <var>A</var> and <var>B</var>
    differs, sort <var>A</var> and <var>B</var> by <a>tree order</a>
    of their corresponding <a>owning elements</a>.
    With regard to pseudo-elements, the sort order is as follows:

    *   element
    *   ::marker
    *   ::before
    *   any other pseudo-elements not mentioned specifically in this list,
        sorted in ascending order by the Unicode codepoints that make up each selector
    *   ::after
    *   element children

1.  Otherwise, if <var>A</var> and <var>B</var> have different <a>transition
    generation</a> values, sort by their corresponding
    <a>transition generation</a> in ascending order.

1.  Otherwise, sort <var>A</var> and <var>B</var> in ascending order by the
    Unicode codepoints that make up the <a>expanded transition property
    name</a> of each transition (i.e. without attempting case conversion and
    such that &lsquo;-moz-column-width&rsquo; sorts before
    &lsquo;column-width&rsquo;).

When determining the composite order in order to sort transition events
where either or both of the events is a {{transitioncancel}} event,
use the [=owning element=] and [=transition generation=]
that were set immediately prior to cancelling the transition.

Transitions generated using the markup defined in this specification are
<em>not</em> added to the <a>global animation list</a> when they are created.
Instead, these animations are appended to the <a>global animation list</a> at
the first moment when they transition out of the [=play state/idle|idle play state=] after
being disassociated from their <a>owning element</a>.
Transitions that have been disassociated from their <a>owning element</a>
but are still [=play state/idle=] do not have a defined
composite order.

Note: This behavior relies on the fact that disassociating a transition
from its <a>owning element</a> always causes it to enter (or remain) in the
[=play state/idle|idle play state=].

## Animation cascade level ## {#cascade-level}

Animations with an [=animation class=] of &lsquo;CSS Transition&rsquo;
that have an [=owning element=]
are applied to the &lsquo;Transitions declaration&rsquo; level
of the CSS cascade.
All other animations generated by the markup defined in this specification,
including animations that no longer have an [=owning element=],
are applied to the &lsquo;Animation declarations&rsquo; level of the cascade.
(See [[web-animations-1#applying-the-composited-result]].)

# Transition Events # {#transition-events}

## Event dispatch ## {#event-dispatch}

Note, this is a more general description of event dispatch than that of CSS
Transitions Level 1 [[CSS-TRANSITIONS-1]] since it must account for the
possibility of animations being seeked or reversed using the Web Animations API
[[WEB-ANIMATIONS]]. Furthermore, it is possible using the Web Animations API
to substitute the transition effect with an entirely different effect with
properties not normally used with transitions (e.g. an effect that repeats
multiple times) and hence this section provides a generic definition that
accounts for the full complexity of the Web Animations model.

The [=event target|target=] for a transition event is
the transition's [=owning element=].
If there is no [=owning element=], no transition events are dispatched
(although the [=animation playback events=] defined in Web Animations are still
dispatched at the corresponding {{CSSTransition}} object).

To avoid firing redundant events, the set of events to dispatch is based
on comparing the <a lt="transition phase">phase</a> of the transition in the
previous [=animation frame=] to its current state.

The <dfn>transition phase</dfn> of a transition is initially &lsquo;idle&rsquo;
and is updated on each [=animation frame=] according to
the first matching condition from below:

<dl class=switch>
   <dt>If the transition has no [=associated effect=],
   <dd>
     The transition phase is set according to the first matching condition
     from below:
     <dl class=switch>
       <dt>If the transition has an <a>unresolved</a> [=animation/current time=],
       <dd>The transition phase is &lsquo;idle&rsquo;.
       <dt>If the transition has a [=animation/current time=] &lt; 0,
       <dd>The transition phase is &lsquo;before&rsquo;.
       <dt>Otherwise,
       <dd>The transition phase is &lsquo;after&rsquo;.
     </dl>
   <dt>If the transition has a [=pending play task=]
       or a [=pending pause task=]
       and its phase was previously &lsquo;idle&rsquo; or &lsquo;pending&rsquo;,
   <dd>The transition phase is &lsquo;pending&rsquo;.
   <dt>Otherwise,
   <dd>The transition phase is the
       [[web-animations-1#animation-effect-phases-and-states|phase]] of its
       [=associated effect=].
</dl>

For calculating the {{TransitionEvent/elapsedTime}} of each event, the following
definitions are used:

*   <dfn>interval start</dfn> =
    <code>max(min(-<a>start delay</a>, <a>active duration</a>), 0)</code>
*   <dfn>interval end</dfn> =
    <code>max(min([=associated effect end=] - <a>start delay</a>,
                  <a>active duration</a>), 0)</code>

In the above formulae, references to the <a>start delay</a>, <a>active
duration</a>, <a>current iteration</a>, <a>iteration start</a>, and
[=iteration duration=] of a transition should be understood to refer
to the corresponding properties of the transition's [=associated effect=].

Each time a new [=animation frame=] is established,
the events to dispatch are determined by comparing
the <a>transition phase</a> in the previous and current [=animation frame=]
as follows:

<table class="event-state-transitions">
  <thead>
    <tr>
      <th>Change</th>
      <th>Events dispatched</th>
      <th><dfn>Elapsed time</dfn> (ms)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>idle &rarr; pending or before</td>
      <td>{{transitionrun}}</td>
      <td><a>interval start</a></td>
    </tr>
    <tr>
      <td rowspan="2">idle &rarr; active <a
          href="#multiple-events-note">&#x66d;</a></td>
      <td>{{transitionrun}}</td>
      <td rowspan="2"><a>interval start</a></td>
    </tr>
    <tr>
      <td>{{transitionstart}}</td>
    </tr>
    <tr>
      <td rowspan="3">idle &rarr; after <a
          href="#multiple-events-note">&#x66d;</a></td>
      <td>{{transitionrun}}</td>
      <td rowspan="2"><a>interval start</a></td>
    </tr>
    <tr>
      <td>{{transitionstart}}</td>
    </tr>
    <tr>
      <td>{{transitionend}}</td>
      <td><a>interval end</a></td>
    </tr>
    <tr>
      <td>pending or before &rarr; active</td>
      <td>{{transitionstart}}</td>
      <td><a>interval start</a></td>
    </tr>
    <tr>
      <td rowspan="2">pending or before &rarr; after <a
                      href="#multiple-events-note">&#x66d;</a></td>
      <td>{{transitionstart}}</td>
      <td><a>interval start</a></td>
    </tr>
    <tr>
      <td>{{transitionend}}</td>
      <td><a>interval end</a></td>
    </tr>
    <tr>
      <td>active &rarr; after</td>
      <td>{{transitionend}}</td>
      <td><a>interval end</a></td>
    </tr>
    <tr>
      <td>active &rarr; before</td>
      <td>{{transitionend}}</td>
      <td><a>interval start</a></td>
    </tr>
    <tr>
      <td>after &rarr; active</td>
      <td>{{transitionstart}}</td>
      <td><a>interval end</a></td>
    </tr>
    <tr>
      <td rowspan="2">after &rarr; before <a
                      href="#multiple-events-note">&#x66d;</a></td>
      <td>{{transitionstart}}</td>
      <td><a>interval end</a></td>
    </tr>
    <tr>
      <td>{{transitionend}}</td>
      <td><a>interval start</a></td>
    </tr>
    <tr>
      <td><em>not</em> idle and <em>not</em> after &rarr; idle</td>
      <td>{{transitioncancel}}</td>
      <td>The <a>active time</a> of the animation at the moment it was canceled
          calculated using a <a>fill mode</a> of both.</td>
    </tr>
  </tbody>
</table>

<p id="multiple-events-note">&#x66d; Where multiple events are listed for
a state change, all events are dispatched in the order listed and in immediate
succession.</p>

Since the <a>elapsed time</a> defined in the table and procedure above is
expressed in milliseconds, it must be divided by 1,000 to produce a value in
seconds before being assigned to the {{TransitionEvent/elapsedTime}} member of
the {{TransitionEvent}}.

<div class="note">

  The above state transition chart ensures that, with the exception of
  transitions that are paused or have an infinite running time, the following
  invariants hold:

  * For every {{transitionrun}} event there will be a exactly one
    {{transitionend}} <em>or</em> {{transitioncancel}} and never both.
  * For every {{transitionstart}} event there will be a exactly one
    {{transitionend}} <em>or</em> {{transitioncancel}} and never both.
  * Every {{transitionend}} event is preceded by a corresponding
    {{transitionstart}} event.

  The typical sequences of events, then, are as follows:

  * Regular playback: {{transitionrun}}, {{transitionstart}}, {{transitionend}}.
  * Interrupted playback: {{transitionrun}}, {{transitionstart}},
    {{transitioncancel}}.
  * Interrupted playback during delay or pending phase: {{transitionrun}},
    {{transitioncancel}}.
  * Reversed playback after completion: {{transitionrun}}, {{transitionstart}},
    {{transitionend}}, {{transitionstart}}, {{transitionend}}.

</div>

# DOM Interfaces # {#interface-dom}

## The CSSTransition interface ## {#the-CSSTransition-interface}

<pre class="idl">
[Exposed=Window]
interface CSSTransition : Animation {
  readonly attribute CSSOMString transitionProperty;
};
</pre>

:   <dfn attribute for=CSSTransition>transitionProperty</dfn>
::  The <a>expanded transition property name</a> of this transition.

## Requirements on pending style changes ## {#requirements-on-pending-style-changes}

Various operations may affect the <a lt="computed value">computed values</a> of
properties on elements. User agents may, as an optimization, defer recomputing
these values until it becomes necessary.
However, all operations included in programming interface defined in this
specification, as well as those operations defined in Web Animations
[[!WEB-ANIMATIONS]] that may return objects defined by this specification,
must produce a result consistent with having fully processed any such pending
changes to computed values.

<div class="note">
As an example, in the following code fragment, when the specified value of
<code>elem</code>'s 'opacity' property is updated, a user agent may defer
recalculating the computed value of the 'opacity' property.

The first time this occurs, calling {{Window/getComputedStyle(elt)}} and
subsequently accessing the <code>opacity</code> property of the result will
cause the user agent to recompute the value of opacity.

After the 'opacity' property is updated a second time, the
{{Animatable/getAnimations()}} method is called on <code>elem</code>.
This method is specified by Web Animations and can return {{CSSTransition}}
objects as defined in this specification.
Hence, as result of the requirements in this section, the user agent must apply
any pending style changes thus generating a new {{CSSTransition}} for the
'opacity' property before returning its result.

<div><pre class="example lang-javascript">
elem.style.transition = 'opacity 100s';
elem.style.opacity = '0';
window.getComputedStyle(elem).opacity; // 0
elem.style.opacity = '1';
elem.getAnimations()[0].transitionProperty // 'opacity'
</pre></div>

</div>

<h2 id=privacy>Privacy Considerations</h2>

No new privacy considerations have been reported on this specification.

<h2 id=security>Security Considerations</h2>

No new security considerations have been reported on this specification.

<h2 id="changes">Changes</h2>

<h3 id="changes-20230905">Changes since First Public Working Draft (5 September 2023)</h3>

<ul>
  <li>Define the order of {{transitioncancel}} events.</li>
</ul>

<h3 id="changes-fpwd">Changes since Level 1, in First Public Working Draft</h3>

<ul>
  <li>Transitions can now occur on discretely-animatable properties.  The
  newly-introduced 'transition-behavior' property allows opting in to this behavior.</li>

  <li>The ''@starting-style'' rule
  (and {{CSSStartingStyleRule}} interface)
  is introduced to allow
  transitions on elements whose style changes
  from not being rendered to being rendered.</li>

  <li>Interactions with the Web Animations API are more clearly specified:

  <ul>

    <li>The {{CSSTransition}} interface is defined.</li>

    <li>The composite order of the generated animations is defined.</li>

    <li>The animation class of the generated animations is defined.</li>

    <li>The cascade level of animation objects that were created from transitions
    and then reused through the Web Animations API is defined,
    along with the concept of [=owning element=] needed to define it.</li>

    <li>The rules for event dispatch have been specified to explain what happens
    when the animations are seeked or reversed using the Web Animations API.</li>

    <li>Interaction of the Web Animations API with
    the rules for faster reversing of interrupted transitions
    is specified.</li>

    <li>[[#requirements-on-pending-style-changes]] are specified.</li>
  </ul>

  <li>The handling of transitions on elements
  that are no longer being rendered
  is more clearly defined
  (the transitions are canceled
  and removed from the set of completed transitions).</li>

</ul>

<h2 id="issues-common">Issues commonly raised as issues with previous levels</h2>

  <p>
    These issues were commonly reported issues
    with the previous level of the specification.
  </p>

  <div class="issue">
    <p>
      More powerful timing function syntax
      is a common request from developers.
      See, for example:
      <a href="https://lists.w3.org/Archives/Public/www-style/2013Jun/0376.html">2013 message</a>
      or
      <a href="https://lists.w3.org/Archives/Public/public-fx/2015JulSep/thread.html#msg34">2015 thread</a>.
    </p>
  </div>

  <div class="issue">
    <p>
      Developers frequently have to trigger style flushes
      in order to force transitions to start.
      It would be good to have an API
      that would avoid this requirement.
      See, for example,
      <a href="https://lists.w3.org/Archives/Public/www-style/2011Mar/0729.html">2011 proposal</a>.
    </p>
  </div>

<h2 id="issues-spec">Issues deferred from previous levels of the spec</h2>

  <p>
    These issues were in previous levels of the specification,
    but may not turn out to be important in this level either.
  </p>

  <div class="issue">
    We may ultimately want to support a keypath syntax
    for the 'transition-property' property.
    A keypath syntax
    would enable different transitions
    to be specified
    for components of a property.
    For example
    the blur of a shadow
    could have
    a different transition
    than the color of a shadow.
  </div>
